package ginx

import (
	"net/http"

	"gitee.com/youkelike/zlog"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
)

// L 使用包变量
var L = zlog.Default()

func WrapToken[C jwt.Claims](fn func(ctx *gin.Context, uc C) (Result, error)) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		val, ok := ctx.Get("users")
		if !ok {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		c, ok := val.(C)
		if !ok {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		// rw := &responseWriter{
		// 	StatusCode:     http.StatusOK,
		// 	ResponseWriter: ctx.Writer,
		// }
		// ctx.Writer = rw

		res, err := fn(ctx, c)
		if err != nil {
			L.Errorw("处理业务逻辑出错",
				zlog.String("path", ctx.Request.URL.Path),
				// 命中的路由
				zlog.String("route", ctx.FullPath()),
				zlog.Err(err))
		}
		// 直接能拿到响应码
		ctx.JSON(ctx.Writer.Status(), res)
		// ctx.JSON(rw.StatusCode, res)
	}
}

func WrapBodyAndToken[Req any, C jwt.Claims](fn func(ctx *gin.Context, req Req, uc C) (Result, error)) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		var req Req
		if err := ctx.Bind(&req); err != nil {
			return
		}

		val, ok := ctx.Get("users")
		if !ok {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		c, ok := val.(C)
		if !ok {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		// rw := &responseWriter{
		// 	StatusCode:     http.StatusOK,
		// 	ResponseWriter: ctx.Writer,
		// }
		// ctx.Writer = rw

		res, err := fn(ctx, req, c)
		if err != nil {
			L.Errorw("处理业务逻辑出错",
				zlog.String("path", ctx.Request.URL.Path),
				// 命中的路由
				zlog.String("route", ctx.FullPath()),
				zlog.Err(err))
		}
		// 直接能拿到响应码
		ctx.JSON(ctx.Writer.Status(), res)
		// ctx.JSON(rw.StatusCode, res)
	}
}

// T 就是 dto
func WrapBody[T any](fn func(ctx *gin.Context, req T) (Result, error)) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		var req T
		if err := ctx.Bind(&req); err != nil {
			return
		}

		// rw := &responseWriter{
		// 	StatusCode:     http.StatusOK,
		// 	ResponseWriter: ctx.Writer,
		// }
		// ctx.Writer = rw

		res, err := fn(ctx, req)
		if err != nil {
			L.Errorw("处理业务逻辑出错",
				zlog.String("path", ctx.Request.URL.Path),
				// 命中的路由
				zlog.String("route", ctx.FullPath()),
				zlog.Err(err))
		}
		// 直接能拿到响应码
		ctx.JSON(ctx.Writer.Status(), res)
		// ctx.JSON(rw.StatusCode, res)
	}
}

// type responseWriter struct {
// 	StatusCode int
// 	gin.ResponseWriter
// }

// func (w responseWriter) WriteHeader(statusCode int) {
// 	w.StatusCode = statusCode
// 	w.ResponseWriter.WriteHeader(statusCode)
// }
